package yoyoorm

import (
	"context"
	"database/sql"
	"fmt"
	"gin-c/frame"
	"math"
	"reflect"
	"regexp"
	"strconv"
	"strings"
	"time"

	_ "github.com/go-sql-driver/mysql"
	"github.com/jmoiron/sqlx"
	"github.com/redis/go-redis/v9"
	"github.com/tidwall/buntdb"
	_ "modernc.org/sqlite"
)

// WhereData 类型的Go等价结构
type WhereData struct {
	Field    string
	Operator string
	Value    interface{}
	Param    []interface{}
	Subquery bool
}

// Logic 逻辑条件
type Logic string

const (
	AND Logic = "AND"
	OR  Logic = "OR"
)

// Order 排序规则
type Order string

const (
	ASC  Order = "ASC"
	DESC Order = "DESC"
)

// WhereArr 类型的Go等价结构
type WhereArr [][]interface{}

// ResultSet 查询结果集
type ResultSet struct {
	Data     []map[string]interface{}
	Count    int
	MaxCount int
	Fields   []string
}

// ResultSetPages 查询结果集分页
type ResultSetPages struct {
	Data     []map[string]interface{}
	Count    int
	MaxCount int
	Fields   []string
	MaxPage  int
}

// TransactionConn 事务连接
type TransactionConn struct {
	Tx *sqlx.Tx
}

// DatabaseType 数据库类型
type DatabaseType string

const (
	MYSQL  DatabaseType = "mysql"
	SQLITE DatabaseType = "sqlite"
)

// YoyoORM 主类
type YoyoORM struct {
	Pool        *sqlx.DB
	IsShowSql   bool
	PrintMethod func(string, func(string) string)
	DbType      DatabaseType
}

// YoyoORMClass 连接方式默认采用连接池方式处理
type YoyoORMClass struct {
	Db     *sqlx.DB
	Tx     *sqlx.Tx
	Tables string
	Fields []string
	Logic  Logic
	Wheres []struct {
		Type Logic
		Data WhereData
	}
	Groups  map[string]bool
	Havings string
	Orders  []struct {
		Field string
		Order Order
	}
	Joins []struct {
		Type  string
		Table string
		Where string
	}
	Limits interface{}
	DbType DatabaseType
}

var (
	// 全局连接池
	_POOL *sqlx.DB
	// 是否显示sql语句
	IsShowSql bool = false
	// 全局数据库类型
	_DBTYPE DatabaseType = MYSQL
	// 设置打印sql语句的方法
	PrintMethod = func(sql string, highlightSQL func(string) string) {
		fmt.Println("YoyoORM:", highlightSQL(sql))
	}
)

// FormatValue 格式化值
func FormatValue(value interface{}) interface{} {
	if str, ok := value.(string); ok {
		return fmt.Sprintf("'%s'", str) // 如果是字符串，在其前后添加单引号
	} else if num, ok := value.(int); ok {
		return num // 如果是数字，直接返回
	} else if num, ok := value.(float64); ok {
		return num // 如果是浮点数，直接返回
	}
	return value
}

// FillStr 生成指定数量的占位符
func FillStr(arr []interface{}, str string, decollator string) string {
	if str == "" {
		str = "?"
	}
	if decollator == "" {
		decollator = ","
	}

	placeholders := make([]string, len(arr))
	for i := range arr {
		placeholders[i] = str
	}
	return strings.Join(placeholders, decollator)
}

// IsOperator 判断是否是操作符
func IsOperator(value string) bool {
	operators := []string{"=", "<>", "<", "<=", ">", ">=", "LIKE", "IN", "NOT IN", "IS NULL", "IS NOT NULL", "BETWEEN", "NOT BETWEEN", "REGEXP", "NOT REGEXP", "NOT LIKE"}
	value = strings.ToUpper(value) // 转成大写
	for _, op := range operators {
		if value == op {
			return true
		}
	}
	return false
}

// IsTypeof 判断类型
func IsTypeof(data interface{}) string {
	return strings.ToLower(fmt.Sprintf("%T", data))
}

// IsObject 判断是否是对象
func IsObject(data interface{}) bool {
	if data == nil {
		return false
	}

	kind := reflect.TypeOf(data).Kind()
	return kind == reflect.Map || kind == reflect.Struct
}

// IsTwoArray 判断是否是二维数组
func IsTwoArray(arr interface{}) bool {
	if arr == nil {
		return false
	}

	value := reflect.ValueOf(arr)
	if value.Kind() != reflect.Slice {
		return false
	}

	for i := 0; i < value.Len(); i++ {
		if value.Index(i).Kind() != reflect.Slice {
			return false
		}
	}

	return true
}

// IsArrayObj 判断是否是数组对象
func IsArrayObj(arr interface{}) bool {
	if arr == nil {
		return false
	}

	value := reflect.ValueOf(arr)
	if value.Kind() != reflect.Slice {
		return false
	}

	for i := 0; i < value.Len(); i++ {
		if !IsObject(value.Index(i).Interface()) {
			return false
		}
	}

	return true
}

// IsArrayData 判断是否是单纯的数组数据
func IsArrayData(arr interface{}) bool {
	if arr == nil {
		return false
	}

	value := reflect.ValueOf(arr)
	if value.Kind() != reflect.Slice {
		return false
	}

	for i := 0; i < value.Len(); i++ {
		if value.Index(i).Kind() == reflect.Map || value.Index(i).Kind() == reflect.Struct || value.Index(i).Kind() == reflect.Slice {
			return false
		}
	}

	return true
}

// CreatePool 创建连接池
func CreatePool(dbType DatabaseType, config string) *YoyoORM {
	var err error

	if _POOL != nil {
		return &YoyoORM{
			Pool:        _POOL,
			IsShowSql:   IsShowSql,
			PrintMethod: PrintMethod,
			DbType:      _DBTYPE,
		}
	}

	// 创建连接池，设置连接池的参数
	_POOL, err = sqlx.Connect(string(dbType), config)
	if err != nil {
		panic(err)
	}

	// 设置连接池配置
	_POOL.SetMaxOpenConns(100)
	_POOL.SetMaxIdleConns(10)
	_POOL.SetConnMaxLifetime(time.Hour)

	_DBTYPE = dbType

	return &YoyoORM{
		Pool:        _POOL,
		IsShowSql:   IsShowSql,
		PrintMethod: PrintMethod,
		DbType:      dbType,
	}
}

// Table 设置表名
func (y *YoyoORM) Table(tableName string) *YoyoORMClass {
	return (&YoyoORMClass{Db: y.Pool, DbType: y.DbType}).Table(tableName)
}

// Table 设置表名
func Table(tableName string) *YoyoORMClass {
	return (&YoyoORMClass{Db: _POOL, DbType: _DBTYPE}).Table(tableName)
}

// BeginTransaction 开启事务（在(执行结束-提交)或者(报错时-回滚)自动释放连接）
func BeginTransaction(callback func(conn *TransactionConn) error, isError bool) (bool, error) {
	tx, err := _POOL.Beginx()
	if err != nil {
		return false, err
	}

	conn := &TransactionConn{Tx: tx}

	err = callback(conn)
	if err != nil {
		tx.Rollback()
		if isError {
			return false, err
		}
		return false, nil
	}

	err = tx.Commit()
	if err != nil {
		tx.Rollback()
		if isError {
			return false, err
		}
		return false, nil
	}

	return true, nil
}

// GetOneConnection 获取一条连接（在执行结束或者报错时自动释放连接）
func GetOneConnection(callback func(conn *TransactionConn) (interface{}, error)) (interface{}, error) {
	tx, err := _POOL.Beginx()
	if err != nil {
		return nil, err
	}

	conn := &TransactionConn{Tx: tx}

	result, err := callback(conn)
	if err != nil {
		tx.Rollback()
		return nil, err
	}

	err = tx.Commit()
	if err != nil {
		tx.Rollback()
		return nil, err
	}

	return result, nil
}

// Query 执行sql查询语句
func Query(sql string, values ...interface{}) (*sqlx.Rows, error) {
	return _POOL.Queryx(sql, values...)
}

// Execute 执行sql语句
func Execute(sql string, values ...interface{}) (sql.Result, error) {
	return _POOL.Exec(sql, values...)
}

// SetPool 设置额外指定连接池
func SetPool(pool *sqlx.DB, dbType DatabaseType) {
	_POOL = pool
	_DBTYPE = dbType
}

// 处理不同数据库的标识符括起方式
func (y *YoyoORMClass) quoteIdentifier(identifier string) string {
	// 如果已经包含了表别名，则需要特殊处理
	if strings.Contains(identifier, " AS ") || strings.Contains(identifier, " as ") {
		parts := regexp.MustCompile(`(?i)^(\w+)\s+(as\s+)?(\w+)$`).FindStringSubmatch(identifier)
		if len(parts) == 4 {
			if y.DbType == SQLITE {
				return fmt.Sprintf("\"%s\" AS %s", parts[1], parts[3])
			}
			return fmt.Sprintf("`%s` AS %s", parts[1], parts[3])
		}
	}

	// 处理常规标识符
	if y.DbType == SQLITE {
		return fmt.Sprintf("\"%s\"", identifier)
	}
	return fmt.Sprintf("`%s`", identifier)
}

// Table 设置表名
func (y *YoyoORMClass) Table(tableName string) *YoyoORMClass {
	reg := regexp.MustCompile(`^(\w+)\s+(as\s+)?(\w+)$`)
	tableName = strings.TrimSpace(tableName)

	if reg.MatchString(tableName) {
		matches := reg.FindStringSubmatch(tableName)
		if y.DbType == SQLITE {
			y.Tables = fmt.Sprintf("\"%s\" AS %s", matches[1], matches[3])
		} else {
			y.Tables = fmt.Sprintf("`%s` AS %s", matches[1], matches[3])
		}
	} else {
		y.Tables = y.quoteIdentifier(tableName) // 设置表名
	}

	y.Logic = AND // 设置默认逻辑为AND
	y.Groups = make(map[string]bool)

	return y
}

// Field 添加查询字段
func (y *YoyoORMClass) Field(field interface{}) *YoyoORMClass {
	switch f := field.(type) {
	case string:
		y.Fields = append(y.Fields, f)
	case []string:
		y.Fields = append(y.Fields, f...)
	}

	return y
}

// Order 对查询结果集进行排序
func (y *YoyoORMClass) Order(field interface{}, order ...Order) *YoyoORMClass {
	if len(order) == 0 {
		switch f := field.(type) {
		case string:
			y.Orders = append(y.Orders, struct {
				Field string
				Order Order
			}{Field: f, Order: ASC})
		case map[string]Order:
			for k, v := range f {
				y.Orders = append(y.Orders, struct {
					Field string
					Order Order
				}{Field: k, Order: v})
			}
		}
	} else {
		y.Orders = append(y.Orders, struct {
			Field string
			Order Order
		}{Field: field.(string), Order: order[0]})
	}

	return y
}

// Group 添加字段分组
func (y *YoyoORMClass) Group(fields interface{}) *YoyoORMClass {
	switch f := fields.(type) {
	case string:
		y.Groups[f] = true
	case []string:
		for _, v := range f {
			y.Groups[v] = true
		}
	}

	return y
}

// Having 过滤由 GROUP BY 产生的结果集中的重复记录
func (y *YoyoORMClass) Having(where string) *YoyoORMClass {
	if len(y.Groups) == 0 {
		panic("The group method must be called before the having method")
	}

	y.Havings = where
	return y
}

// Limit 添加结果集返回数量限制
func (y *YoyoORMClass) Limit(args ...int) *YoyoORMClass {
	if len(args) == 1 {
		y.Limits = args[0]
	} else if len(args) == 2 {
		y.Limits = []int{args[0], args[1]}
	} else {
		panic("The limit method can only accept one or two parameters")
	}

	return y
}

// LeftJoin 多表联查[左查询](LEFT JOIN)
func (y *YoyoORMClass) LeftJoin(table string, where string) *YoyoORMClass {
	reg := regexp.MustCompile(`^(\w+)\s+(as\s+)?(\w+)$`)
	table = strings.TrimSpace(table)

	if reg.MatchString(table) {
		matches := reg.FindStringSubmatch(table)
		if y.DbType == SQLITE {
			table = fmt.Sprintf("\"%s\" AS %s", matches[1], matches[3])
		} else {
			table = fmt.Sprintf("`%s` AS %s", matches[1], matches[3])
		}
	} else {
		table = y.quoteIdentifier(table) // 设置表名
	}

	y.Joins = append(y.Joins, struct {
		Type  string
		Table string
		Where string
	}{Type: "LEFT", Table: table, Where: where})

	return y
}

// RightJoin 多表联查[右查询](RIGHT JOIN)
func (y *YoyoORMClass) RightJoin(table string, where string) *YoyoORMClass {
	reg := regexp.MustCompile(`^(\w+)\s+(as\s+)?(\w+)$`)
	table = strings.TrimSpace(table)

	if reg.MatchString(table) {
		matches := reg.FindStringSubmatch(table)
		if y.DbType == SQLITE {
			table = fmt.Sprintf("\"%s\" AS %s", matches[1], matches[3])
		} else {
			table = fmt.Sprintf("`%s` AS %s", matches[1], matches[3])
		}
	} else {
		table = y.quoteIdentifier(table) // 设置表名
	}

	y.Joins = append(y.Joins, struct {
		Type  string
		Table string
		Where string
	}{Type: "RIGHT", Table: table, Where: where})

	return y
}

// Join 多表联查[等值查询](INNER JOIN)
func (y *YoyoORMClass) Join(table string, where string) *YoyoORMClass {
	reg := regexp.MustCompile(`^(\w+)\s+(as\s+)?(\w+)$`)
	table = strings.TrimSpace(table)

	if reg.MatchString(table) {
		matches := reg.FindStringSubmatch(table)
		if y.DbType == SQLITE {
			table = fmt.Sprintf("\"%s\" AS %s", matches[1], matches[3])
		} else {
			table = fmt.Sprintf("`%s` AS %s", matches[1], matches[3])
		}
	} else {
		table = y.quoteIdentifier(table) // 设置表名
	}

	y.Joins = append(y.Joins, struct {
		Type  string
		Table string
		Where string
	}{Type: "INNER", Table: table, Where: where})

	return y
}

// FullJoin 多表联查[一个匹配填充null返回](FULL JOIN)
func (y *YoyoORMClass) FullJoin(table string, where string) *YoyoORMClass {
	// SQLite 不支持 FULL JOIN
	if y.DbType == SQLITE {
		panic("SQLite does not support FULL JOIN")
	}

	reg := regexp.MustCompile(`^(\w+)\s+(as\s+)?(\w+)$`)
	table = strings.TrimSpace(table)

	if reg.MatchString(table) {
		matches := reg.FindStringSubmatch(table)
		table = fmt.Sprintf("`%s` AS %s", matches[1], matches[3])
	} else {
		table = fmt.Sprintf("`%s`", table) // 设置表名
	}

	y.Joins = append(y.Joins, struct {
		Type  string
		Table string
		Where string
	}{Type: "FULL", Table: table, Where: where})

	return y
}

// whereComposite where集合处理方法(包含where的AND和OR)
func (y *YoyoORMClass) whereComposite(field interface{}, args ...interface{}) *YoyoORMClass {
	switch f := field.(type) {
	case [][]interface{}:
		// 数组
		for _, item := range f {
			if len(item) == 3 {
				y.whereComposite(item[0], item[1], item[2])
			}
		}
		return y
	case string:
		if len(args) >= 2 {
			op, ok := args[0].(string)
			if !ok {
				panic("operator must be string")
			}

			op = strings.ToUpper(op) // 转成大写
			if !IsOperator(op) {
				panic("operator error")
			}

			if !strings.Contains(f, ".") {
				// 根据数据库类型选择标识符
				if y.DbType == SQLITE {
					f = fmt.Sprintf("\"%s\"", f)
				} else {
					f = fmt.Sprintf("`%s`", f) // 如果字段没有点就加上反引号
				}
			}

			whereDatav := WhereData{
				Field:    f,
				Operator: op,
				Value:    args[1],
				Param:    []interface{}{},
				Subquery: false, // 不是子查询
			}

			if array, ok := args[1].([]interface{}); ok {
				// 值是数组
				if op != "IN" && op != "NOT IN" {
					panic("The operator should be IN or NOT IN when the array is passed.")
				}

				whereDatav.Value = fmt.Sprintf("(%s)", FillStr(array, "?", ","))
				whereDatav.Param = array
			}

			y.Wheres = append(y.Wheres, struct {
				Type Logic
				Data WhereData
			}{Type: y.Logic, Data: whereDatav})

			return y
		} else if len(args) == 1 {
			switch v := args[0].(type) {
			case map[string]interface{}:
				// 把对象都分解成一一对应的(有很多个)
				for key, val := range v {
					y.whereComposite(key, "=", val)
				}
				return y
			case func() *YoyoORMClass:
				// 这里需要额外处理（因为是sql预处理和参数列表）
				result := v()
				if result == nil {
					panic("where callback must return YoyoORM")
				}

				// 构建sql语句
				sqlResult := result.BuildSql("select")

				if !strings.Contains(f, ".") {
					// 根据数据库类型选择标识符
					if y.DbType == SQLITE {
						f = fmt.Sprintf("\"%s\"", f)
					} else {
						f = fmt.Sprintf("`%s`", f) // 如果字段没有点就加上反引号
					}
				}

				// 需要将参数列表融合进来
				y.Wheres = append(y.Wheres, struct {
					Type Logic
					Data WhereData
				}{
					Type: y.Logic,
					Data: WhereData{
						Field:    f,
						Operator: "=",
						Value:    sqlResult.Sql,
						Param:    sqlResult.Params,
						Subquery: true, // 是子查询
					},
				})

				return y
			default:
				return y.whereComposite(f, "=", v)
			}
		}
	}

	panic("where params error")
}

// WhereIn 添加一条IN条件(子查询)
func (y *YoyoORMClass) WhereIn(field string, callback func() *YoyoORMClass) *YoyoORMClass {
	// 需要额外处理（需要融合sql和参数列表）
	result := callback()
	if result == nil {
		panic("whereIn callback must return YoyoORM")
	}

	// 构建sql语句
	sqlResult := result.BuildSql("select")

	if !strings.Contains(field, ".") {
		// 根据数据库类型选择标识符
		if y.DbType == SQLITE {
			field = fmt.Sprintf("\"%s\"", field)
		} else {
			field = fmt.Sprintf("`%s`", field) // 如果字段没有点就加上反引号
		}
	}

	y.Wheres = append(y.Wheres, struct {
		Type Logic
		Data WhereData
	}{
		Type: y.Logic,
		Data: WhereData{
			Field:    field,
			Operator: "IN",
			Value:    sqlResult.Sql,
			Param:    sqlResult.Params,
			Subquery: true, // 是子查询
		},
	})

	return y
}

// Where 添加一条AND条件
func (y *YoyoORMClass) Where(field interface{}, args ...interface{}) *YoyoORMClass {
	// 设置当前逻辑为 AND
	y.Logic = AND
	return y.whereComposite(field, args...)
}

// WhereOr 添加一条OR条件
func (y *YoyoORMClass) WhereOr(field interface{}, args ...interface{}) *YoyoORMClass {
	// 设置当前逻辑为 OR
	y.Logic = OR
	// 调用 where 方法
	return y.whereComposite(field, args...)
}

// Find 查询指定条件的单条数据
func (y *YoyoORMClass) Find() (map[string]interface{}, error) {
	y.Limits = 1 // 设置限制条数
	sqlResult := y.buildSelect()

	var result map[string]interface{}

	// 使用sqlx的NamedQuery，支持自动类型转换
	rows, err := y.Db.Queryx(sqlResult.Sql, sqlResult.Params...)
	if err != nil {
		return nil, err
	}
	defer rows.Close()

	if rows.Next() {
		// 使用sqlx自动将数据映射到map
		result = make(map[string]interface{})
		err = rows.MapScan(result)
		if err != nil {
			return nil, err
		}

		// 自动处理[]byte类型转换为string
		for k, v := range result {
			if b, ok := v.([]byte); ok {
				result[k] = string(b)
			}

			// 处理日期类型
			if t, ok := v.(time.Time); ok {
				result[k] = t.Format("2006-01-02 15:04:05")
			}
		}

		return result, nil
	}

	return nil, nil
}

// Select 查询指定条件的数据
func (y *YoyoORMClass) Select() (*ResultSet, error) {
	sqlResult := y.buildSelect()

	// 使用sqlx的Queryx，支持自动类型转换
	rows, err := y.Db.Queryx(sqlResult.Sql, sqlResult.Params...)
	if err != nil {
		return nil, err
	}
	defer rows.Close()

	columns, err := rows.Columns()
	if err != nil {
		return nil, err
	}

	var result []map[string]interface{}

	for rows.Next() {
		// 使用sqlx自动将数据映射到map
		entry := make(map[string]interface{})
		err = rows.MapScan(entry)
		if err != nil {
			return nil, err
		}

		// 自动处理[]byte类型转换为string和日期格式化
		for k, v := range entry {
			if b, ok := v.([]byte); ok {
				entry[k] = string(b)
			}

			// 处理日期类型
			if t, ok := v.(time.Time); ok {
				entry[k] = t.Format("2006-01-02 15:04:05")
			}
		}

		result = append(result, entry)
	}

	return &ResultSet{
		Data:     result,
		Count:    len(result),
		MaxCount: len(result),
		Fields:   columns,
	}, nil
}

// Pages 查询指定条件的数据分页
func (y *YoyoORMClass) Pages(page int, count int) (*ResultSetPages, error) {
	if page < 1 {
		page = 1
	}
	if count < 1 {
		count = 1
	}

	result, err := GetOneConnection(func(conn *TransactionConn) (interface{}, error) {
		// 创建一个新的查询构建器实例
		newBuilder := &YoyoORMClass{
			Db:      y.Db,
			Tx:      y.Tx,
			Tables:  y.Tables,
			Fields:  append([]string{}, y.Fields...),
			Wheres:  y.Wheres,
			Groups:  y.Groups,
			Havings: y.Havings,
			Orders:  y.Orders,
			Joins:   y.Joins,
			DbType:  y.DbType,
		}

		// 添加count字段到最后
		newBuilder.Fields = []string{"COUNT(*) as total_count"}
		newBuilder.Limits = 1 // 设置限制条数

		sqlResult := newBuilder.buildSelect()

		var totalCount int
		err := conn.Tx.QueryRowx(sqlResult.Sql, sqlResult.Params...).Scan(&totalCount)
		if err != nil {
			return nil, err
		}

		// 计算分页信息
		offset := (page - 1) * count
		maxPage := int(math.Ceil(float64(totalCount) / float64(count)))
		if maxPage < 1 {
			maxPage = 1
		}

		// 恢复字段并移除计数字段
		newBuilder.Fields = y.Fields

		// 设置limit
		newBuilder.Limits = []int{offset, count}

		// 构建新的查询
		newSql := newBuilder.buildSelect()

		// 执行查询
		rows, err := conn.Tx.Queryx(newSql.Sql, newSql.Params...)
		if err != nil {
			return nil, err
		}
		defer rows.Close()

		columns, err := rows.Columns()
		if err != nil {
			return nil, err
		}

		var resultData []map[string]interface{}

		for rows.Next() {
			// 使用sqlx自动将数据映射到map
			entry := make(map[string]interface{})
			err = rows.MapScan(entry)
			if err != nil {
				return nil, err
			}

			// 自动处理[]byte类型转换为string和日期格式化
			for k, v := range entry {
				if b, ok := v.([]byte); ok {
					entry[k] = string(b)
				}

				// 处理日期类型
				if t, ok := v.(time.Time); ok {
					entry[k] = t.Format("2006-01-02 15:04:05")
				}
			}

			resultData = append(resultData, entry)
		}

		return &ResultSetPages{
			Data:     resultData,
			Count:    len(resultData),
			MaxCount: totalCount,
			Fields:   columns,
			MaxPage:  maxPage,
		}, nil
	})

	if err != nil {
		return nil, err
	}

	return result.(*ResultSetPages), nil
}

// Delete 删除指定条件的数据
func (y *YoyoORMClass) Delete() (sql.Result, error) {
	sqlResult := y.buildDelete()
	return y.Db.Exec(sqlResult.Sql, sqlResult.Params...)
}

// Insert 插入一条或者多条数据
func (y *YoyoORMClass) Insert(data interface{}) (sql.Result, error) {
	sqlResult := y.buildInsert(data)
	return y.Db.Exec(sqlResult.Sql, sqlResult.Params...)
}

// Update 修改指定条件的所有数据
func (y *YoyoORMClass) Update(data interface{}) (sql.Result, error) {
	sqlResult := y.buildUpdate(data)
	return y.Db.Exec(sqlResult.Sql, sqlResult.Params...)
}

// SelectStruct 使用结构体映射结果集
func (y *YoyoORMClass) SelectStruct(dest interface{}) error {
	sqlResult := y.buildSelect()

	// 使用sqlx的Select方法将结果映射到结构体切片
	return y.Db.Select(dest, sqlResult.Sql, sqlResult.Params...)
}

// SelectRow 查询单行数据并映射到结构体
func (y *YoyoORMClass) SelectRow(dest interface{}) error {
	y.Limits = 1 // 设置限制条数
	sqlResult := y.buildSelect()

	// 使用sqlx的Get方法将结果映射到结构体
	return y.Db.Get(dest, sqlResult.Sql, sqlResult.Params...)
}

// buildWhere 构建where条件
func (y *YoyoORMClass) buildWhere() *struct {
	where  string
	params []interface{}
} {
	where := y.Wheres
	if len(where) == 0 {
		return nil
	}

	// where分组
	var whereGroup [][]struct {
		Type Logic
		Data WhereData
	}

	// 最小分组
	var minGroup []struct {
		Type Logic
		Data WhereData
	}

	for i, eachWhere := range where {
		if len(minGroup) == 0 {
			minGroup = append(minGroup, eachWhere)
			continue
		}

		minWhereLast := minGroup[len(minGroup)-1]

		// 判断当前条件是否和上一个条件是同一个逻辑(相同就同个组)
		if minWhereLast.Type == eachWhere.Type {
			minGroup = append(minGroup, eachWhere)
			continue
		}

		// 和上个条件不是相同的需要（清空小分组添加到大分组去）
		if i == len(where)-1 {
			// 最后一个条件(不同但是需要添加进前面的分组里面)
			minGroup = append(minGroup, eachWhere)
		} else {
			whereGroup = append(whereGroup, minGroup)
			minGroup = []struct {
				Type Logic
				Data WhereData
			}{eachWhere} // 重置小分组(为当前的)
		}
	}

	// 最后一个分组需要添加到大分组去
	whereGroup = append(whereGroup, minGroup)

	// 最终生成where语句
	ultimately := struct {
		where  string
		params []interface{}
	}{
		where:  "",
		params: []interface{}{},
	}

	for i, eachGroupWhere := range whereGroup {
		whereMinGroupSqlArr := []string{}      // 最小分组sql语句
		whereMinGroupValArr := []interface{}{} // 最小分组参数

		for j, eachWhere := range eachGroupWhere {
			// 判断是否是in数组
			if eachWhere.Data.Subquery {
				// 子查询
				whereMinGroupSqlArr = append(whereMinGroupSqlArr, fmt.Sprintf("%s %s (%s)", eachWhere.Data.Field, eachWhere.Data.Operator, eachWhere.Data.Value))
				whereMinGroupValArr = append(whereMinGroupValArr, eachWhere.Data.Param...)
				continue
			}

			if len(eachWhere.Data.Param) > 0 {
				whereMinGroupSqlArr = append(whereMinGroupSqlArr, fmt.Sprintf("%s %s (%s)", eachWhere.Data.Field, eachWhere.Data.Operator, FillStr(eachWhere.Data.Param, "?", ",")))
				whereMinGroupValArr = append(whereMinGroupValArr, eachWhere.Data.Param...)
				continue
			}

			prefix := ""
			if j > 0 {
				prefix = fmt.Sprintf(" %s ", eachWhere.Type)
			}

			whereMinGroupSqlArr = append(whereMinGroupSqlArr, fmt.Sprintf("%s%s %s ?", prefix, eachWhere.Data.Field, eachWhere.Data.Operator))
			whereMinGroupValArr = append(whereMinGroupValArr, eachWhere.Data.Value)
		}

		if i > 0 {
			ultimately.where += fmt.Sprintf(" %s ", eachGroupWhere[0].Type)
		}

		ultimately.where += fmt.Sprintf("(%s)", strings.Join(whereMinGroupSqlArr, ""))
		ultimately.params = append(ultimately.params, whereMinGroupValArr...)
	}

	return &ultimately
}

// buildSelect 构建Select类型的语句
func (y *YoyoORMClass) buildSelect() struct {
	Sql    string
	Params []interface{}
} {
	table := y.Tables
	field := y.Fields
	params := []interface{}{} // 参数
	sqlArr := []string{"SELECT"}

	if len(field) > 0 {
		sqlArr = append(sqlArr, strings.Join(field, ","))
	} else {
		sqlArr = append(sqlArr, "*")
	}

	sqlArr = append(sqlArr, fmt.Sprintf("FROM %s", table))

	// 构建join条件
	if len(y.Joins) > 0 {
		joinArr := []string{}
		for _, j := range y.Joins {
			joinArr = append(joinArr, fmt.Sprintf("%s JOIN %s ON %s", j.Type, j.Table, j.Where))
		}
		sqlArr = append(sqlArr, strings.Join(joinArr, " "))
	}

	// 构建where条件
	resultWhere := y.buildWhere()
	if resultWhere != nil {
		sqlArr = append(sqlArr, "WHERE", resultWhere.where) // 添加where条件
		params = append(params, resultWhere.params...)      // 添加参数
	}

	// 构建group条件
	if len(y.Groups) > 0 {
		groups := []string{}
		for g := range y.Groups {
			groups = append(groups, g)
		}
		sqlArr = append(sqlArr, fmt.Sprintf("GROUP BY %s", strings.Join(groups, ",")))
	}

	// 构建having条件
	if y.Havings != "" {
		sqlArr = append(sqlArr, fmt.Sprintf("HAVING %s", y.Havings))
	}

	// 构建order条件
	if len(y.Orders) > 0 {
		orderArr := []string{}
		for _, o := range y.Orders {
			field := o.Field
			if strings.Contains(field, ".") {
				// 处理包含点的字段，根据数据库类型选择不同的引号
				parts := strings.Split(field, ".")
				if y.DbType == SQLITE {
					field = fmt.Sprintf("\"%s\".\"%s\"", parts[0], parts[1])
				} else {
					field = fmt.Sprintf("`%s`.`%s`", parts[0], parts[1])
				}
			} else {
				// 处理不包含点的字段
				if y.DbType == SQLITE {
					field = fmt.Sprintf("\"%s\"", field)
				} else {
					field = fmt.Sprintf("`%s`", field)
				}
			}
			orderArr = append(orderArr, fmt.Sprintf("%s %s", field, o.Order))
		}
		sqlArr = append(sqlArr, fmt.Sprintf("ORDER BY %s", strings.Join(orderArr, ",")))
	}

	// 构建limit条件
	if y.Limits != nil {
		var limitStr string

		switch limit := y.Limits.(type) {
		case []int:
			// SQLite和MySQL的LIMIT语法略有不同
			if y.DbType == SQLITE {
				limitStr = fmt.Sprintf("LIMIT %d OFFSET %d", limit[1], limit[0])
			} else {
				limitStr = fmt.Sprintf("LIMIT %d, %d", limit[0], limit[1])
			}
		case int:
			limitStr = fmt.Sprintf("LIMIT %d", limit)
		}

		sqlArr = append(sqlArr, limitStr) // 添加limit条件
	}

	// 打印SQL
	if IsShowSql {
		logSql(strings.Join(sqlArr, " "), params)
	}

	return struct {
		Sql    string
		Params []interface{}
	}{
		Sql:    strings.Join(sqlArr, " "),
		Params: params,
	}
}

// buildDelete 构建Delete类型的语句
func (y *YoyoORMClass) buildDelete() struct {
	Sql    string
	Params []interface{}
} {
	table := y.Tables
	params := []interface{}{} // 参数
	sqlArr := []string{"DELETE"}

	sqlArr = append(sqlArr, fmt.Sprintf("FROM %s", table))

	// 构建join条件
	if len(y.Joins) > 0 {
		joinArr := []string{}
		for _, j := range y.Joins {
			joinArr = append(joinArr, fmt.Sprintf("%s JOIN %s ON %s", j.Type, j.Table, j.Where))
		}
		sqlArr = append(sqlArr, strings.Join(joinArr, " "))
	}

	// 构建where条件
	resultWhere := y.buildWhere()
	if resultWhere != nil {
		sqlArr = append(sqlArr, "WHERE", resultWhere.where) // 添加where条件
		params = append(params, resultWhere.params...)      // 添加参数
	}

	// 构建order条件
	if len(y.Orders) > 0 {
		orderArr := []string{}
		for _, o := range y.Orders {
			field := o.Field
			if strings.Contains(field, ".") {
				// 处理包含点的字段，根据数据库类型选择不同的引号
				parts := strings.Split(field, ".")
				if y.DbType == SQLITE {
					field = fmt.Sprintf("\"%s\".\"%s\"", parts[0], parts[1])
				} else {
					field = fmt.Sprintf("`%s`.`%s`", parts[0], parts[1])
				}
			} else {
				// 处理不包含点的字段
				if y.DbType == SQLITE {
					field = fmt.Sprintf("\"%s\"", field)
				} else {
					field = fmt.Sprintf("`%s`", field)
				}
			}
			orderArr = append(orderArr, fmt.Sprintf("%s %s", field, o.Order))
		}
		sqlArr = append(sqlArr, fmt.Sprintf("ORDER BY %s", strings.Join(orderArr, ",")))
	}

	// 构建limit条件
	if y.Limits != nil {
		var limitStr string

		switch limit := y.Limits.(type) {
		case []int:
			// SQLite和MySQL的LIMIT语法略有不同
			if y.DbType == SQLITE {
				limitStr = fmt.Sprintf("LIMIT %d OFFSET %d", limit[1], limit[0])
			} else {
				limitStr = fmt.Sprintf("LIMIT %d, %d", limit[0], limit[1])
			}
		case int:
			limitStr = fmt.Sprintf("LIMIT %d", limit)
		}

		sqlArr = append(sqlArr, limitStr) // 添加limit条件
	}

	// 打印SQL
	if IsShowSql {
		logSql(strings.Join(sqlArr, " "), params)
	}

	return struct {
		Sql    string
		Params []interface{}
	}{
		Sql:    strings.Join(sqlArr, " "),
		Params: params,
	}
}

// buildInsert 构建Insert类型的语句
func (y *YoyoORMClass) buildInsert(data interface{}) struct {
	Sql    string
	Params []interface{}
} {
	table := y.Tables
	field := y.Fields
	params := []interface{}{}         // 参数
	paramsMatrix := [][]interface{}{} // 参数(二维数组)
	sqlArr := []string{"INSERT"}

	sqlArr = append(sqlArr, fmt.Sprintf("INTO %s", table))

	// 处理数据函数
	processingData := func(data interface{}) {
		if IsObject(data) {
			// 处理Map类型
			if mapData, ok := data.(map[string]interface{}); ok {
				field = []string{}
				rowParams := []interface{}{}

				for k, v := range mapData {
					if y.DbType == SQLITE {
						field = append(field, fmt.Sprintf("\"%s\"", k))
					} else {
						field = append(field, fmt.Sprintf("`%s`", k))
					}
					rowParams = append(rowParams, v)
				}

				paramsMatrix = append(paramsMatrix, rowParams)
				return
			}

			// 处理结构体类型 - 使用sqlx的反射功能
			val := reflect.ValueOf(data)
			if val.Kind() == reflect.Ptr {
				val = val.Elem()
			}
			typ := val.Type()

			field = []string{}
			rowParams := []interface{}{}

			for i := 0; i < val.NumField(); i++ {
				// 获取字段tag
				fieldName := typ.Field(i).Name
				tag := typ.Field(i).Tag.Get("db")
				if tag != "" && tag != "-" {
					fieldName = tag
				}

				if y.DbType == SQLITE {
					field = append(field, fmt.Sprintf("\"%s\"", fieldName))
				} else {
					field = append(field, fmt.Sprintf("`%s`", fieldName))
				}
				rowParams = append(rowParams, val.Field(i).Interface())
			}

			paramsMatrix = append(paramsMatrix, rowParams)
			return
		}

		if !reflect.ValueOf(data).IsValid() || reflect.ValueOf(data).IsNil() {
			panic("The inserted data must be an object or array with a value")
		}

		val := reflect.ValueOf(data)

		if val.Kind() != reflect.Slice && val.Kind() != reflect.Array {
			panic("The inserted data must be an object or array with a value")
		}

		if val.Len() <= 0 {
			panic("The data you submit is empty")
		}

		if IsTwoArray(data) {
			// 二维数组
			for i := 0; i < val.Len(); i++ {
				row := val.Index(i)
				rowParams := []interface{}{}

				for j := 0; j < row.Len(); j++ {
					rowParams = append(rowParams, row.Index(j).Interface())
				}

				paramsMatrix = append(paramsMatrix, rowParams)
			}
			return
		}

		if IsArrayObj(data) {
			// 对象数组
			firstItem := val.Index(0).Interface()

			field = []string{}

			// 从第一个对象获取字段
			if mapData, ok := firstItem.(map[string]interface{}); ok {
				for k := range mapData {
					if y.DbType == SQLITE {
						field = append(field, fmt.Sprintf("\"%s\"", k))
					} else {
						field = append(field, fmt.Sprintf("`%s`", k))
					}
				}
			} else {
				// 结构体
				firstVal := reflect.ValueOf(firstItem)
				if firstVal.Kind() == reflect.Ptr {
					firstVal = firstVal.Elem()
				}
				firstType := firstVal.Type()

				for i := 0; i < firstType.NumField(); i++ {
					// 获取字段tag
					fieldName := firstType.Field(i).Name
					tag := firstType.Field(i).Tag.Get("db")
					if tag != "" && tag != "-" {
						fieldName = tag
					}

					if y.DbType == SQLITE {
						field = append(field, fmt.Sprintf("\"%s\"", fieldName))
					} else {
						field = append(field, fmt.Sprintf("`%s`", fieldName))
					}
				}
			}

			// 获取每个对象的值
			for i := 0; i < val.Len(); i++ {
				item := val.Index(i).Interface()
				rowParams := []interface{}{}

				if mapData, ok := item.(map[string]interface{}); ok {
					for _, k := range field {
						fieldName := strings.Trim(k, "`\"")
						rowParams = append(rowParams, mapData[fieldName])
					}
				} else {
					// 结构体
					itemVal := reflect.ValueOf(item)
					if itemVal.Kind() == reflect.Ptr {
						itemVal = itemVal.Elem()
					}

					for j := 0; j < itemVal.NumField(); j++ {
						rowParams = append(rowParams, itemVal.Field(j).Interface())
					}
				}

				paramsMatrix = append(paramsMatrix, rowParams)
			}
			return
		}

		if IsArrayData(data) {
			// 一维数组
			rowParams := []interface{}{}

			for i := 0; i < val.Len(); i++ {
				rowParams = append(rowParams, val.Index(i).Interface())
			}

			paramsMatrix = append(paramsMatrix, rowParams)
			return
		}

		panic("The inserted data must be an object or array with a value")
	}

	processingData(data)

	if len(field) <= 0 {
		panic("The data you submit has no fields")
	}

	sqlArr = append(sqlArr, fmt.Sprintf("(%s)", strings.Join(field, ",")))
	sqlArr = append(sqlArr, "VALUES")

	valueStrs := []string{}

	for _, p := range paramsMatrix {
		placeholders := make([]string, len(p))
		for i := range p {
			placeholders[i] = "?"
			params = append(params, p[i])
		}
		valueStrs = append(valueStrs, fmt.Sprintf("(%s)", strings.Join(placeholders, ",")))
	}

	sqlArr = append(sqlArr, strings.Join(valueStrs, ","))

	// 打印SQL
	if IsShowSql {
		logSql(strings.Join(sqlArr, " "), params)
	}

	return struct {
		Sql    string
		Params []interface{}
	}{
		Sql:    strings.Join(sqlArr, " "),
		Params: params,
	}
}

// buildUpdate 构建Update类型的语句
func (y *YoyoORMClass) buildUpdate(data interface{}) struct {
	Sql    string
	Params []interface{}
} {
	table := y.Tables
	params := []interface{}{} // 参数
	sqlArr := []string{"UPDATE"}

	sqlArr = append(sqlArr, table)

	// 构建join条件
	if len(y.Joins) > 0 {
		joinArr := []string{}
		for _, j := range y.Joins {
			joinArr = append(joinArr, fmt.Sprintf("%s JOIN %s ON %s", j.Type, j.Table, j.Where))
		}
		sqlArr = append(sqlArr, strings.Join(joinArr, " "))
	}

	sqlArr = append(sqlArr, "SET")

	// 构建set条件
	checkSet := func() {
		if mapData, ok := data.(map[string]interface{}); ok {
			// 对象就是直接设置将指定key设置指定value
			arr := []string{}

			for field, value := range mapData {
				if y.DbType == SQLITE {
					arr = append(arr, fmt.Sprintf("\"%s\" = ?", field))
				} else {
					arr = append(arr, fmt.Sprintf("`%s` = ?", field))
				}
				params = append(params, value)
			}

			sqlArr = append(sqlArr, strings.Join(arr, ","))
			return
		}

		// 处理结构体类型 - 使用sqlx的反射功能
		val := reflect.ValueOf(data)
		if val.Kind() == reflect.Ptr {
			val = val.Elem()
		}

		if val.Kind() == reflect.Struct {
			typ := val.Type()
			arr := []string{}

			for i := 0; i < val.NumField(); i++ {
				// 获取字段tag
				fieldName := typ.Field(i).Name
				tag := typ.Field(i).Tag.Get("db")
				if tag != "" && tag != "-" {
					fieldName = tag
				}

				if y.DbType == SQLITE {
					arr = append(arr, fmt.Sprintf("\"%s\" = ?", fieldName))
				} else {
					arr = append(arr, fmt.Sprintf("`%s` = ?", fieldName))
				}
				params = append(params, val.Field(i).Interface())
			}

			sqlArr = append(sqlArr, strings.Join(arr, ","))
			return
		}

		if IsTwoArray(data) {
			// 二维数组
			arr := []string{}
			val := reflect.ValueOf(data)

			for i := 0; i < val.Len(); i++ {
				row := val.Index(i)
				if row.Len() >= 2 {
					arr = append(arr, fmt.Sprintf("%s = %s", row.Index(0).String(), row.Index(1).String()))
				}
			}

			sqlArr = append(sqlArr, strings.Join(arr, ","))
			return
		}

		if IsArrayData(data) {
			// 一维数组
			val := reflect.ValueOf(data)

			if val.Len() == 3 {
				// [field, operator, value]
				sqlArr = append(sqlArr, fmt.Sprintf("%s %s", val.Index(0).String(), val.Index(1).String()))
				params = append(params, val.Index(2).Interface())
				return
			}
		}

		panic("You can only submit data in the form of arrays, two-dimensional arrays, structs, and objects")
	}

	checkSet()

	// 构建where条件
	resultWhere := y.buildWhere()
	if resultWhere != nil {
		sqlArr = append(sqlArr, "WHERE", resultWhere.where) // 添加where条件
		params = append(params, resultWhere.params...)      // 添加参数
	}

	// 构建order条件
	if len(y.Orders) > 0 {
		orderArr := []string{}
		for _, o := range y.Orders {
			field := o.Field
			if strings.Contains(field, ".") {
				// 处理包含点的字段，根据数据库类型选择不同的引号
				parts := strings.Split(field, ".")
				if y.DbType == SQLITE {
					field = fmt.Sprintf("\"%s\".\"%s\"", parts[0], parts[1])
				} else {
					field = fmt.Sprintf("`%s`.`%s`", parts[0], parts[1])
				}
			} else {
				// 处理不包含点的字段
				if y.DbType == SQLITE {
					field = fmt.Sprintf("\"%s\"", field)
				} else {
					field = fmt.Sprintf("`%s`", field)
				}
			}
			orderArr = append(orderArr, fmt.Sprintf("%s %s", field, o.Order))
		}
		sqlArr = append(sqlArr, fmt.Sprintf("ORDER BY %s", strings.Join(orderArr, ",")))
	}

	// 打印SQL
	if IsShowSql {
		logSql(strings.Join(sqlArr, " "), params)
	}

	return struct {
		Sql    string
		Params []interface{}
	}{
		Sql:    strings.Join(sqlArr, " "),
		Params: params,
	}
}

// BuildSql 构建sql语句
func (y *YoyoORMClass) BuildSql(type_ ...string) struct {
	Sql    string
	Params []interface{}
} {
	sqlType := "select"
	if len(type_) > 0 {
		sqlType = type_[0]
	}

	switch sqlType {
	case "select":
		return y.buildSelect()
	case "insert":
		panic("For insert, you need to provide data parameter")
	case "update":
		panic("For update, you need to provide data parameter")
	case "delete":
		return y.buildDelete()
	default:
		panic("Unknown type")
	}
}

// Table TransactionConn的Table方法
func (t *TransactionConn) Table(table string) *YoyoORMClass {
	return (&YoyoORMClass{Tx: t.Tx, DbType: _DBTYPE}).Table(table)
}

// Execute TransactionConn的Execute方法
func (t *TransactionConn) Execute(sql string, values ...interface{}) (sql.Result, error) {
	return t.Tx.Exec(sql, values...)
}

// Query TransactionConn的Query方法
func (t *TransactionConn) Query(sql string, values ...interface{}) (*sqlx.Rows, error) {
	return t.Tx.Queryx(sql, values...)
}

// NamedQuery 执行命名查询
func (t *TransactionConn) NamedQuery(query string, arg interface{}) (*sqlx.Rows, error) {
	return t.Tx.NamedQuery(query, arg)
}

// NamedExec 执行命名命令
func (t *TransactionConn) NamedExec(query string, arg interface{}) (sql.Result, error) {
	return t.Tx.NamedExec(query, arg)
}

// Get 获取单条记录到结构体
func (t *TransactionConn) Get(dest interface{}, query string, args ...interface{}) error {
	return t.Tx.Get(dest, query, args...)
}

// Select 获取多条记录到结构体切片
func (t *TransactionConn) Select(dest interface{}, query string, args ...interface{}) error {
	return t.Tx.Select(dest, query, args...)
}

// logSql 打印SQL
func logSql(sql string, bind interface{}) {
	var bindParams []interface{}

	switch b := bind.(type) {
	case [][]interface{}:
		// 二维数组，展平
		for _, row := range b {
			bindParams = append(bindParams, row...)
		}
	case []interface{}:
		bindParams = b
	default:
		bindParams = []interface{}{bind}
	}

	logSql := sql

	for _, v := range bindParams {
		var strValue string

		switch val := v.(type) {
		case string:
			strValue = fmt.Sprintf("'%s'", val)
		case bool:
			strValue = fmt.Sprintf("'%t'", val)
		case time.Time:
			strValue = fmt.Sprintf("'%s'", val.Format("2006-01-02 15:04:05"))
		default:
			strValue = fmt.Sprintf("%v", val)
		}

		// 使用非贪婪匹配防止替换错误
		re := regexp.MustCompile(`([\s=])?\?(\s)?`)
		logSql = re.ReplaceAllString(logSql, "${1}"+strValue+"${2}")
	}

	PrintMethod(logSql, highlightSql)
}

// highlightSql 高亮SQL// highlightSql 高亮SQL
func highlightSql(sql string) string {
	// 这里简单实现，实际上需要更复杂的SQL解析
	keywords := []string{
		"SELECT", "FROM", "WHERE", "INSERT", "UPDATE", "DELETE",
		"JOIN", "LEFT", "RIGHT", "INNER", "FULL", "ON", "AS",
		"GROUP", "BY", "HAVING", "ORDER", "LIMIT", "OFFSET",
		"VALUES", "SET", "AND", "OR", "NOT", "IN", "LIKE",
		"IS", "NULL", "BETWEEN", "ASC", "DESC",
	}

	for _, keyword := range keywords {
		pattern := fmt.Sprintf(`(?i)\b%s\b`, keyword)
		re := regexp.MustCompile(pattern)
		sql = re.ReplaceAllString(sql, "\x1b[35m"+strings.ToUpper(keyword)+"\x1b[0m")
	}

	// 函数高亮（简化版本）
	functions := []string{"COUNT", "SUM", "AVG", "MAX", "MIN"}
	for _, function := range functions {
		pattern := fmt.Sprintf(`(?i)\b%s\b`, function)
		re := regexp.MustCompile(pattern)
		sql = re.ReplaceAllString(sql, "\x1b[31m"+strings.ToUpper(function)+"\x1b[0m")
	}

	// 引号内的字符串高亮
	re := regexp.MustCompile(`'[^']*'`)
	sql = re.ReplaceAllStringFunc(sql, func(s string) string {
		return "\x1b[32m" + s + "\x1b[0m"
	})

	// 标识符高亮
	re = regexp.MustCompile(`[\` + "`" + `"]\w+[\` + "`" + `"]`)
	sql = re.ReplaceAllStringFunc(sql, func(s string) string {
		return "\x1b[36m" + s + "\x1b[0m"
	})

	// 数字高亮
	re = regexp.MustCompile(`\b\d+\b`)
	sql = re.ReplaceAllStringFunc(sql, func(s string) string {
		return "\x1b[33m" + s + "\x1b[0m"
	})

	return sql
}

var DBY *YoyoORM

var Cache = &cacheStuct{}

type cacheStuct struct {
	Link *buntdb.DB
	Rs   *redis.Client
	Ctx  context.Context
}

// 获取指定缓存String
func (c cacheStuct) Get(key string) (string, error) {
	var value string
	if frame.Config.Server.Cache == "redis" {
		return Cache.Rs.Get(Cache.Ctx, key).Result()
	}
	err := Cache.Link.View(func(tx *buntdb.Tx) error {
		val, err := tx.Get(key)
		if err != nil {
			return err
		}
		value = val
		return nil
	})
	return value, err
}

// 设置指定缓存
func (c cacheStuct) Set(key string, value string, expiration time.Duration) error {
	if frame.Config.Server.Cache == "redis" {
		return Cache.Rs.Set(Cache.Ctx, key, value, expiration).Err()
	}
	opts := &buntdb.SetOptions{Expires: true, TTL: expiration}
	return Cache.Link.Update(func(tx *buntdb.Tx) error {
		_, _, err := tx.Set(key, value, opts)
		return err
	})
}

// 删除指定缓存
func (c cacheStuct) Delete(key string) error {
	if frame.Config.Server.Cache == "redis" {
		_, err := Cache.Rs.Del(Cache.Ctx, key).Result()
		if err != nil {
			return err
		}
		return nil
	}
	return Cache.Link.Update(func(tx *buntdb.Tx) error {
		_, err := tx.Delete(key)
		return err
	})
}

// 获取指定缓存的剩余时间
func (c cacheStuct) Ttl(key string) (time.Duration, error) {
	var ttl time.Duration

	if frame.Config.Server.Cache == "redis" {
		ttl, err := Cache.Rs.PTTL(Cache.Ctx, key).Result()
		if err != nil {
			return ttl, err
		}
		return ttl, nil
	}

	err := Cache.Link.View(func(tx *buntdb.Tx) error {
		ttlc, err := tx.TTL(key) // 返回秒级剩余时间
		if err != nil {
			return err
		}
		ttl = ttlc
		return nil
	})
	return ttl, err
}

func init() {
	if frame.Config.Server.Database == "mysql" {
		// 创建MySQL连接
		DBY = CreatePool(MYSQL, fmt.Sprintf("%v:%v@tcp(%v:%v)/%v?charset=utf8mb4&parseTime=True",
			frame.Config.Database.MySQL.User,
			frame.Config.Database.MySQL.Password,
			frame.Config.Database.MySQL.Host,
			frame.Config.Database.MySQL.Port,
			frame.Config.Database.MySQL.Database,
		))
	} else {
		// 创建SQLite连接
		DBY = CreatePool(SQLITE, "file:"+frame.Config.Database.SQLite.Path)
	}

	// 缓存配置
	switch frame.Config.Server.Cache {
	case "redis":
		// 创建Redis连接
		Cache.Rs = redis.NewClient(&redis.Options{
			Addr:     frame.Config.Database.Redis.Host + ":" + strconv.Itoa(frame.Config.Database.Redis.Port), // Redis 地址
			Password: frame.Config.Database.Redis.Password,                                                    // 密码
			DB:       frame.Config.Database.Redis.Database,                                                    // 数据库编号
		})
		// 测试连接
		Cache.Ctx = context.Background()
		_, err := Cache.Rs.Ping(Cache.Ctx).Result()
		if err != nil {
			panic(err)
		}

	case "file":
		db, err := buntdb.Open("CacheFile.db")
		if err != nil {
			panic(err)
		}
		Cache.Link = db
	default:
		// 默认使用内存缓存
		db, err := buntdb.Open(":memory:")
		if err != nil {
			panic(err)
		}
		Cache.Link = db
	}

}
